package cn.b.sky.admin.controller;

import cn.b.sky.common.utils.DatabaseUtils;
import cn.b.sky.admin.constants.SystemConstant;
import cn.b.sky.admin.enums.DwzCallbackType;
import cn.b.sky.admin.enums.DwzStatusCode;
import cn.b.sky.admin.exception.ManagementException;
import cn.b.sky.admin.model.BatchJobReport;
import cn.b.sky.admin.model.DWZResult;
import cn.b.sky.admin.utils.AjaxUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.web.bind.annotation.ExceptionHandler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;

public class BaseController {

  protected static final Logger LOGGER = LoggerFactory.getLogger(BaseController.class);

  protected static final String NAVTABID = "navTabId";

  @ExceptionHandler
  public String exp(HttpServletRequest request, HttpServletResponse response, Exception ex) {
    String errorMsg = "";
    //记录下日志
    LOGGER.error("{}", ex);
    if (ex instanceof ManagementException) {
      // 抛出的是错误代码这里进行一次国际化处理
      errorMsg = getManagementExceptionMessage(ex);
    } else if (ex instanceof DataIntegrityViolationException) {

      errorMsg = getDataIntegrityViolationExceptionMessage(ex);

    } else {

      errorMsg = SystemConstant.DWZ_CODE_ERROR_MESSAGE;
    }

    if (AjaxUtil.isAjax(request)) {
      response.setHeader("Content-Type", "application/json;charset=UTF-8");
      response.setContentType("application/json;charset=UTF-8");
      String jsonObject = JSONObject.toJSONString(AjaxUtil.ajaxError(errorMsg, ex.getMessage()));
      PrintWriter out = null;
      try {

        out = response.getWriter();
        out.print(jsonObject);
        out.flush();
      } catch (IOException e) {

        LOGGER.error("{}", e);
      } finally {
        if (out != null) {
          out.close();
        }
      }
      return null;
    } else {
      request.setAttribute("message", errorMsg);
      request.setAttribute("errorMessage", ex.getMessage());
      // 根据不同错误转向不同页面
      return "error/ime_exception";
    }
  }

  private String getDataIntegrityViolationExceptionMessage(Exception ex) {

    String errorMsg = ex.getMessage();
    if (DatabaseUtils.isConstraintsError(errorMsg)) {
      // 外键删除已存在提示
      errorMsg = SystemConstant.DATABASE_OPERATION_FK;
    }
    return errorMsg;
  }

  private String getManagementExceptionMessage(Exception ex) {
    ManagementException exception = (ManagementException) ex;
    return exception.getMessage();
  }

  public DWZResult getDWZJsonObject(DwzStatusCode statusCode, String message, String navTabId, String rel,
      DwzCallbackType callbackType, String forwardUrl, String confirmMsg, Object data) {
    DWZResult dwzResult = null;

    if (null == statusCode) {// 回调状态
      LOGGER.error("Dwz 的状态码statusCode为null，异常状态。");
      return null;
    }
    if (null == callbackType) {// 回调状态
      callbackType = DwzCallbackType.EMPTY;
    }
    dwzResult = new DWZResult(statusCode.getValue(), message, navTabId, rel, callbackType.getValue(), forwardUrl,
        confirmMsg, data);
    return dwzResult;
  }

  /**
   * 
   * <strong>Title : navTabAjaxDone<br></strong>
   * <strong>Description : </strong>TODO@方法注释说明写在此处@<br> 
   * <strong>Create on : 2016-6-7 上午10:33:04<br></strong>
   * <p>
   * @param navTabId 窗口id
   * @param rel 窗口id
   * @param callbackType 回调类型
   * @param forwardUrl 转发url
   * @param confirmMsg 确认的消息提示
   * @param data 返回的数据
   * @return
   * DWZResult
   * @throws 
   * @author lidapeng<br>
   * @version <strong>v1.0.0</strong><br>
   * <br>
   * <strong>修改历史:</strong><br>
   * 修改人 | 修改日期 | 修改描述<br>
   * -------------------------------------------<br>
   * <br>
   * <br>
   */
  public DWZResult navTabAjaxDone(String navTabId, String rel, DwzCallbackType callbackType, String forwardUrl,
      String confirmMsg, Object data) {
    return navTabAjaxDone(SystemConstant.DWZ_CODE_OK_MESSAGE, navTabId, rel, callbackType, forwardUrl, confirmMsg, data);
  }

  /**
   * 
   * <strong>Title : navTabAjaxDone<br></strong>
   * <strong>Description : </strong>TODO@方法注释说明写在此处@<br> 
   * <strong>Create on : 2016-6-7 上午10:33:04<br></strong>
   * <p>
   * @param message 消息提示
   * @param navTabId 窗口id
   * @param rel 窗口id
   * @param callbackType 回调类型
   * @param forwardUrl 转发url
   * @param confirmMsg 确认的消息提示
   * @param data 返回的数据
   * @return
   * DWZResult
   * @throws 
   * @author lidapeng<br>
   * @version <strong>v1.0.0</strong><br>
   * <br>
   * <strong>修改历史:</strong><br>
   * 修改人 | 修改日期 | 修改描述<br>
   * -------------------------------------------<br>
   * <br>
   * <br>
   */
  public DWZResult navTabAjaxDone(String message, String navTabId, String rel, DwzCallbackType callbackType,
      String forwardUrl, String confirmMsg, Object data) {
    return getDWZJsonObject(DwzStatusCode.OK, message, navTabId, rel, callbackType, forwardUrl, confirmMsg, data);
  }

  public DWZResult dialogAjaxDone(String navTabId, String rel, String forwardUrl, Object data) {
    return dialogAjaxDone(SystemConstant.DWZ_CODE_OK_MESSAGE, navTabId, rel, forwardUrl, data);
  }

  /**
   * 
   * <strong>Title : dialogAjaxDone<br></strong>
   * <strong>Description : </strong>dialogAjaxDone<br> 
   * <strong>Create on : 2016-6-7 上午10:33:17<br></strong>
   * <p>
   * @param message 消息提示
   * @param navTabId 窗口id
   * @param rel 窗口id
   * @param forwardUrl 转发url
   * @param data 返回的数据
   * @return
   * DWZResult
   * @throws 
   * @author lidapeng<br>
   * @version <strong>v1.0.0</strong><br>
   * <br>
   * <strong>修改历史:</strong><br>
   * 修改人 | 修改日期 | 修改描述<br>
   * -------------------------------------------<br>
   * <br>
   * <br>
   */
  public DWZResult dialogAjaxDone(String message, String navTabId, String rel, String forwardUrl, Object data) {
    return getDWZJsonObject(DwzStatusCode.OK, message, navTabId, rel, DwzCallbackType.CLOSECURRENT, forwardUrl, null,
        data);
  }

  public DWZResult ajaxDone(Object data) {
    return ajaxDone(SystemConstant.DWZ_CODE_OK_MESSAGE, data);
  }

  /**
   * 
   * <strong>Title : ajaxDone<br></strong>
   * <strong>Description : </strong>通用的异步单一事件返回<br> 
   * <strong>Create on : 2016-6-7 上午10:37:30<br></strong>
   * <p>
   * @param message 提示信息
   * @param data 返回值
   * @return
   * DWZResult
   * @throws 
   * @author lidapeng<br>
   * @version <strong>v1.0.0</strong><br>
   * <br>
   * <strong>修改历史:</strong><br>
   * 修改人 | 修改日期 | 修改描述<br>
   * -------------------------------------------<br>
   * <br>
   * <br>
   */
  public DWZResult ajaxDone(String message, Object data) {
    return getDWZJsonObject(DwzStatusCode.OK, message, null, null, DwzCallbackType.EMPTY, null, null, data);
  }

  /**
   * 
   * <strong>Title : ajaxError<br></strong>
   * <strong>Description : </strong>处理异常返回信息<br> 
   * <strong>Create on : 2016-6-7 上午10:38:58<br></strong>
   * <p>
   * @param message
   * @return
   * DWZResult
   * @throws 
   * @author lidapeng<br>
   * @version <strong>v1.0.0</strong><br>
   * <br>
   * <strong>修改历史:</strong><br>
   * 修改人 | 修改日期 | 修改描述<br>
   * -------------------------------------------<br>
   * <br>
   * <br>
   */
  public DWZResult ajaxError(String message) {
    return getDWZJsonObject(DwzStatusCode.ERROR, message, null, null, DwzCallbackType.EMPTY, null, null, null);
  }

  /**
   * 
   * <strong>Title : ajaxTimeout<br></strong>
   * <strong>Description : </strong>超时提示<br> 
   * <strong>Create on : 2016-6-7 上午10:39:25<br></strong>
   * <p>
   * @param message
   * @return
   * DWZResult
   * @throws 
   * @author lidapeng<br>
   * @version <strong>v1.0.0</strong><br>
   * <br>
   * <strong>修改历史:</strong><br>
   * 修改人 | 修改日期 | 修改描述<br>
   * -------------------------------------------<br>
   * <br>
   * <br>
   */
  public DWZResult ajaxTimeout(String message) {
    return getDWZJsonObject(DwzStatusCode.TIMEOUT, message, null, null, DwzCallbackType.EMPTY, null, null, null);
  }
  
  /**
   * 
   * <strong>Title : batchjobAjaxDone<br></strong>
   * <strong>Description : </strong>批量删除返回方法<br> 
   * <strong>Create on : 2015-12-21 下午6:07:32<br></strong>
   * <p>
   * @param request
   * @param reports
   * @return
   * DWZResult
   * @throws 
   * @author lidapeng<br>
   * @version <strong>v1.0.0</strong><br>
   * <br>
   * <strong>修改历史:</strong><br>
   * 修改人 | 修改日期 | 修改描述<br>
   * -------------------------------------------<br>
   * <br>
   * <br>
   */
  public DWZResult batchjobAjaxDone(HttpServletRequest request, List<BatchJobReport> reports) {
    return this.batchjobAjaxDone(request, DwzCallbackType.EMPTY, reports);
  }

  /**
   * 
   * <strong>Title : batchjobAjaxDone<br></strong>
   * <strong>Description : </strong>重构下批量作业的返回方法，支持dialog批量操作<br> 
   * <strong>Create on : 2016-4-6 下午6:48:08<br></strong>
   * <p>
   * @param request
   * @param callbackType
   * @param reports
   * @return
   * DWZResult
   * @throws 
   * @author lidapeng<br>
   * @version <strong>v1.0.0</strong><br>
   * <br>
   * <strong>修改历史:</strong><br>
   * 修改人 | 修改日期 | 修改描述<br>
   * -------------------------------------------<br>
   * <br>
   * <br>
   */
  public DWZResult batchjobAjaxDone(HttpServletRequest request, DwzCallbackType callbackType,
                                    List<BatchJobReport> reports) {
    HashMap<String, Object> map = new HashMap<String, Object>();
    map.put("title", "详细报告");
    map.put("data", reports);
    String jsonData = JSON.toJSONString(map);
    String forwardUrl = request.getContextPath() + "/manage/common/showReport";
    return getDWZJsonObject(DwzStatusCode.OK, null, null, null, callbackType, forwardUrl, null, jsonData);
  }
}
